<?php
/**
 * Created by PhpStorm.
 * User: moquan
 * Date: 2018/7/2
 * Time: 11:00
 */

namespace app\admin\model;


use think\Db;
use think\facade\Request;

class MenuModel extends BaseModel {
    const  TYPE = "admin";

    protected $name = 'admin_menu';
    protected $pk = 'id';

    public static function showMenu(){
        //顶部菜单
        //左侧菜单
        //面包屑菜单
    }

    public function setIconAttr ($value) {
        return empty($value) ? 'far fa-circle nav-icon' : $value;
    }

    static function getAdminMenuById( $id ) {
        return self::where( 'id', $id )->find();
    }

    static function getMenuTypes(){
        return array(
            array('type' => 'left', 'text' => '左侧'),
            array('type' => 'btn', 'text' => '按扭')
        );
    }

    static function add( $data ){
        $roles = $data['roles'];
        unset($data['roles']);

        // 启动事务
        Db::startTrans();
        try{
            $id = Db::name('admin_menu')->insert( $data, true, true );

            foreach ($roles as $role_id){
                $roleData['role_id'] = $role_id;
                $roleData['menu_auth'] = explode(',', $id);
                $rows = AdminRole::update( $roleData );
            }

            if ( $rows ) {
                // 提交事务
                Db::commit();
                return true;
            }

            Db::rollback();
            return false;
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            return $e->getMessage();
        }
    }



    /*
     * 顶部菜单
     *
     * */
    public static function getTopMenu( $ids = '' ){
        $condition = [
            'parent_id' => 0,
            'status' => 1
        ];
        if ( $ids && $ids != 'all' ) {
            $condition['id'] = $ids;
        }
        $menu = self::where($condition)->select()->toArray();
        return $menu;
    }

    /*
     * 左侧菜单
     *
     * */
    public static function getAllMenuFormatData( $topID = ''  ){
        $pid = $topID ? $topID : 0;
        $menu = self::order('sort','asc')->select()->toArray();
        return self::getMenuTreeData( $menu, $pid );
    }

    /*
     * 左侧菜单
     *
     * */
    public static function getSidebarMenu( $topID = '', $ids = '' ){
        //取url
        $request = Request::instance();
        $url  = strtolower( $request->module() ).'/'.strtolower( $request->controller() ).'/'.strtolower( $request->action() );
        //获得面包屑
        $location = self::getLocation( $url );
        if( is_array( $location ) ){
            $condition['status'] = 1;
            $condition['menu_type'] = 'left';
            if ( $ids && $ids != 'all' ) {
                $condition['id'] = $ids;
            }
            $menu = self::where( $condition )->order('sort','desc')->select()->toArray();
            $treeData = self::getMenuTreeData( $menu, $location[0]['id'], array_column($location,'id') );
//            dump($treeData);
            $tree = self::getMenuTreeHtml( $treeData );
            return $tree;
        }
        return null;
    }

    /*
     * 获取当前访问
     * */
    public static function getLocation( $url = "" ){
        if( !$url ){
            $request = Request::instance();
            $url  = strtolower( $request->module() ).'/'.strtolower( $request->controller() ).'/'.strtolower( $request->action() );
        }

        $condition = [
            'url_value' => $url,
        ];
        $curr_id  =  self::where($condition)->value('id');

        $location = self::getParents( self::select()->toArray(),$curr_id );

        if( empty( $location ) ){
           return false;
        }
        return $location;
    }

    /*
     * 顶部菜单
     *
     * */
    public static function getOperationAuth( $url, $ids = '' ){
        if ( !$url ) {
            return false;
        }

        $menu = self::get( array('url_value' => $url) );

        $condition = array(
            'parent_id' => $menu->id,
            'menu_type' => 'btn'
        );
        if ( $ids && $ids != 'all' ) {
            $condition['id'] = $ids;
        }

        return self::where( $condition )->select();
    }


    /*
     * 添加打开标识
     * */
    public static function addCurrOpen( &$data, $id = '', $urlValue = '' ){
        foreach ($data as $key => $value){
            if( $id == $value['id'] || ($value['url_value'] && $urlValue == $value['url_value']) ){
                $data[$key]['open'] = true;
                self::addCurrOpen($data, $value['parent_id'] );
            }
        }
        return true;
    }


    /*
     * 获取菜单树结构
     *
     * */
    public static function getMenuTreeData( $array, $pid = 0, $openFlag = [] ){
        $tree = [];
        $menu = array_values( $array );
        foreach ( $menu as $key => $data ){
            if( in_array( $data['id'], $openFlag )){
                $data['open'] = true;
                $data['checked'] = true;
            }

            if ( empty( $data['icon'] ) ) {
                $data['icon'] = 'far fa-circle nav-icon';
            }

            if( $pid == $data['parent_id'] /*&& $data['menu_type'] != 'btn'*/ ){
                $children = self::getMenuTreeData( $menu, $data['id'],$openFlag );
                if( !empty( $children ) ){
                    $data['children'] = $children;
                }
                $data['name'] = $data['menu_name'];
                $tree[] = $data;
            }
        }

        return $tree;
    }

    /*
     * 获取菜单树结构
     *
     * */
    public static function getMenuTreeData_bak( $array, $pid = 0, $url = '', &$unfold = '' ){
        $tree = [];
        $menu = array_values( $array );
        foreach ( $menu as $key => $data ){
            if( $unfold && $unfold == $data['id'] || $data['url_value'] == $url ){
                $data['open'] = true;
                $unfold = !$data['parent_id'] ? $data['id'] : $data['parent_id'] ;
            }

            if( $pid == $data['parent_id'] /*&& $data['menu_type'] != 'btn'*/ ){
                $children = self::getMenuTreeData( $menu, $data['id'],$url, $unfold );
                if( !empty( $children ) ){
                    $data['children'] = $children;
                }
                $tree[] = $data;
            }
        }
        return $tree;
    }

    public static function getMenuTreeHtml( $data, $curr_level = 1 ){
        $is_root = !empty($data[0]) && $curr_level == 1 ? true : false ;
        $ul = $is_root ?"<ul class='nav nav-pills nav-sidebar flex-column' data-widget='treeview' role='menu' data-accordion='false'>":"<ul class='nav nav-treeview'>";

        foreach ($data as $item){
            $open = empty($item['open']) ? '': 'active' ;
            $url = empty($item['url_value']) ? 'javascript:void(0)' : url('/'.$item['url_value']);
            $retract = "style= 'padding-left:".$curr_level * (25)."px'";
            //有子菜单
            if( !empty($item['children']) ){
                $children = self::getMenuTreeHtml( $item['children'], $curr_level + 1 );
                $open1 = !empty($item['open'])? 'menu-open' : '';
                $li = "<li class='nav-item ".$open1."'>
                            <a href='".$url."' class='nav-link ".$open."' {$retract}>
                                <i class='{$item['icon']}'></i>
                                <p>
                                    {$item['menu_name']}
                                <i class='right fa fa-angle-left'></i>
                                </p>
                            </a>
                            {$children}
                        </li>";
            }else{
                $li = "<li class='nav-item ".$open."'>
                            <a href='".$url."' class='nav-link ".$open."' {$retract}>
                                <i class='{$item['icon']}'></i>
                                <p>{$item['menu_name']}</p>
                            </a>
                        </li>";
            }

            $ul .= $li;
        }
        $ul.="</ul>";
        return $ul;
    }

    public static function getSelectMenuTreeHtml( $data, $curr_level = 0, $selected = -1 ){
        $options = $selected == 0 && $curr_level == 0 ? "<option selected value='0'>顶级菜单</option>" : "";
        foreach ($data as $item){
            $fill = '';
            if ( $curr_level ) {
                for ( $i = 0; $i < ($curr_level * 5); $i++ ) {
                    $fill .= '&nbsp;';
                }
            }

            $tabAttr = '';
            if ( $selected == $item['id'] ) {
                $tabAttr = 'selected';
            }
            $option = "<option $tabAttr value='{$item['id']}'>{$fill}{$item['menu_name']}</option>";

            //有子菜单
            if( !empty($item['children']) ){
                $children = self::getSelectMenuTreeHtml( $item['children'], $curr_level + 1, $selected );
                $options .= $option.$children;
            }else{
                $options .= $option;
            }
        }

        return $options;
    }

    public static function getPageMenuTreeHtml( $data, $curr_level = 0 ){
        $html = '';
        foreach ($data as $item){
            $title = "<div class='tree-title' data-pid='{$item['parent_id']}' id='{$item['id']}'>
                          <i class='{$item['icon']}'></i>
                          <span class='tree-title-text'>{$item['menu_name']}</span>
                          <span class='tree-title-url'>{$item['url_value']}</span>
                          <div class='tree-title-btn-group'>
                              <a class='oper oper-add' href='javascript:void(0)'><i class='fa fa-plus fa-fw'></i></a>
                              <a class='oper oper-edit' href='javascript:void(0)'><i class='fa fa-edit fa-fw'></i></a>
                              <a class='oper oper-disabled' href='javascript:void(0)'><i class='fa fa-ban fa-fw'></i></a>
                              <a class='oper oper-del' href='javascript:void(0)'><i class='fa fa-times fa-fw'></i></a>
                          </div>
                       </div>";

            //有子菜单
            if( !empty($item['children']) ){
                $children = self::getPageMenuTreeHtml( $item['children'], $curr_level + 1 );
                $html .= "<li class='tree-item tree-level-{$curr_level}'>
                              ".$title."<ul class='tree-group'>".$children."</ul>
                         </li>";
            }else{
                $html .= "<li class='tree-item tree-level-{$curr_level}'>".$title."</li>";
            }
        }

        return $html;
    }

    /**
     * 根据子节点返回所有父节点
     * @param  array  $lists 数据集
     * @param  string $id    子节点id
     * @return array
     */
    public static function getParents($lists = [], $id = '') {
        $trees = [];
        foreach ($lists as $value) {
            if ($value['id'] == $id) {
                $trees[] = $value;
                $trees   = array_merge(self::getParents($lists, $value['parent_id']), $trees);
            }
        }
        return $trees;
    }

    /**
     * 根据子节点返回所有子节点
     * @param  array  $lists 数据集
     * @param  string $id    子节点id
     * @return array
     */
    public static function getChildren($lists = [], $id = '') {
        $trees = [];
        foreach ($lists as $value) {
            if ($value['parent_id'] == $id) {
                $trees[] = $value;
            }
        }
        return $trees;
    }

    public static function getSubs($categorys,$catId=0,$level=1){
        $subs = array();
        foreach($categorys as $item){
            if($item['parent_id']==$catId ){
                $item['level']=$level;
                $subs[]=$item;
                $subs=array_merge($subs,self::getSubs($categorys,$item['id'],$level+1));
                break;
            }

        }
        return $subs;
    }


    /**
     * 根据父id递归取同级，同级小于等于一个时递归上级同级，同级大于一个时返回空数组
     * @param  array  $lists 数据集
     * @param  string $pid   父级pid
     * @return array
     */
    public static function getSpecialSiblings( $lists, $pid ) {
        $trees = [];
        $num = 0;
        $oneNode = '';
        foreach ($lists as $value) {
            if ($value['parent_id'] == $pid) {
                $trees[] = $value;
                $num++;
            }
            if ( $value['id'] == $pid ) {
                $oneNode = $value;
            }
        }

        if ( $num <= 1 && $oneNode) {
            self::getSpecialSiblings($lists, $oneNode['parent_id']);
            $trees   = array_merge(array($oneNode), $trees);
        } else {
            $trees = [];
        }

        return $trees;
    }

}